home *** CD-ROM | disk | FTP | other *** search
/ Super PC 28 / Super PC 28 (Shareware para Windows 95 y MS-DOS).iso / spc / win / dido3 / source / dido.c next >
Encoding:
C/C++ Source or Header  |  1994-12-15  |  20.2 KB  |  647 lines

  1.  
  2. // don't you leave the...
  3. //
  4. //         D I G I T A L   D O M A I N
  5. //
  6. // lossless digital sound copy from AUDIO CD to WAV files - without crackle & pops!
  7. // No sampling involved. The best quality you can get.
  8. //
  9. // Windows 3.1 freeware by
  10. //                          Michiel Overtoom   (motoom@xs4all.nl)
  11. // Bases on work done by
  12. //                          Yeng-Chee Su       (yenchee@csie.nctu.edu.tw)
  13. // and
  14. //                          Klaas Hemstra      (hst@mh.nl)
  15. //
  16. // and of course... source available.
  17.  
  18. #include <windows.h>
  19. #include <commdlg.h>
  20. #include <dos.h>
  21. #include <stdio.h>
  22. #include <io.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <dir.h>
  26. #include <time.h>
  27. #include <mmsystem.h>            // icm mciSendstring
  28. #include "dido.h"                // defines for program resources
  29.  
  30. #define HELPFILE "dido.hlp"
  31.  
  32. HINSTANCE hinst;
  33. WORD    nbuf;                    // number of low memory dos buffers (set by allocating routine)
  34. #define MAXNBUF 20                // Max. number of low mem buffers that can be allocated
  35. int     CDROM;                     // CDROM unit. 0==a, 1==b, etc
  36. int     lowest, highest;        // Lowest and highest track on the CD
  37. int        lineinc=4,pageinc=12;    // skipping factors for scrollbar (in seconds)
  38. DWORD     total_time;                // Total time on CD
  39. char     s[160],t[80],u[80];        // scratch strings
  40. char    waveditor[160]="MPLAYER.EXE";    // editor for WAV files (INI setting)
  41. BOOL     bit16=1,hz44=1,stereo=1;        // settings from recording dialog; options for
  42.                                         // thinning out the recorded sound.
  43.  
  44. #define mb(x) MessageBox(0,x,"Error",0);
  45.  
  46. #include "didod.h"        // low level cd defines/structs
  47. #include "didod.c"        // low level cd routines via DPMI
  48. #include "didologo.c"    // logo routines
  49.  
  50.  
  51. // Set all the controls in a Dialog to the same font
  52. BOOL CALLBACK EnumDialogChild(HWND hw,LPARAM font) {
  53.     SendMessage(hw,WM_SETFONT,(WPARAM)font,0);
  54.        return 1;
  55.     }
  56. void SetDialogFont(HWND dialog,HFONT font)
  57. {
  58.     EnumChildWindows(dialog,EnumDialogChild,(LPARAM)font);
  59. }
  60.  
  61.  
  62. // Center a window
  63. void CenterWindow(HWND hwnd) 
  64.     RECT r; 
  65.     GetWindowRect(hwnd, &r); 
  66.     SetWindowPos(hwnd, NULL,  
  67.        ((GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2),  
  68.        ((GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2),  
  69.        0, 0, SWP_NOSIZE | SWP_NOACTIVATE);  
  70.  
  71. #include "didorec.c"    // recording routine
  72.  
  73.  
  74. // Delay routine, used in initialization
  75. void delay(long ticks)
  76. {
  77.     long expire=clock()+ticks;
  78.     while(clock()<expire);
  79. }
  80.  
  81.  
  82. // Storage for track table
  83. #define MAXTRACK 100        // Have you ever seen a CD with more than 100 tracks?
  84. int   ntrack=0;                // Nr. of tracks on the CD
  85. int   tracknr[MAXTRACK];    // The track number
  86. DWORD trackloc[MAXTRACK];    // Track start in redbook format
  87. DWORD tracklen[MAXTRACK];    // Duration of track, in sectors
  88.  
  89.  
  90. // Build a table of tracks
  91. int BuildTrackTable(void)
  92. {
  93.     int i;
  94.     DWORD loc;
  95.     // Scan the tracks
  96.     ntrack=0;
  97.     for (i=lowest;i<=highest;i++) {
  98.         if (!GetTrackInfo(i,&loc)) return 0;
  99.         tracknr[ntrack]=i;
  100.         trackloc[ntrack]=loc;
  101.         ntrack++;
  102.         }
  103.     // Calculate the durations
  104.     trackloc[ntrack]=total_time;
  105.     for (i=0;i<ntrack;i++) tracklen[i]=Red2Sierra(trackloc[i+1])-Red2Sierra(trackloc[i]);
  106.     return 1;
  107. }
  108.  
  109.  
  110. // Ask for a WAV file
  111. int ChooseWavFile(HWND hwnd,char *fn)
  112. {
  113.     OPENFILENAME ofn;
  114.     char szFile[128]={0};
  115.     char szFileTitle[128]={0};
  116.     // File uitkiezen
  117.     memset(&ofn, 0, sizeof(ofn));
  118.     strcpy(szFile,fn);
  119.     strcpy(szFileTitle,fn);
  120.     ofn.lStructSize = sizeof(ofn);
  121.     ofn.hwndOwner = hwnd;
  122.     ofn.lpstrFilter = "Wave audio (*.wav)\0*.wav\0";
  123.     ofn.nFilterIndex = 1;
  124.     ofn.lpstrFile= szFile;
  125.     ofn.nMaxFile = 128;
  126.     ofn.lpstrFileTitle= szFileTitle;
  127.     ofn.nMaxFileTitle = 128;
  128.     ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
  129.     if (!GetSaveFileName(&ofn)) return 0;
  130.     strcpy(fn,ofn.lpstrFile);
  131.     return 1;
  132. }
  133.  
  134.  
  135. // Get-a-value dialog proc
  136. struct values {
  137.     DWORD    val;
  138.     DWORD     from;
  139.     DWORD    to; 
  140.     };
  141. #pragma argsused
  142. BOOL CALLBACK ValueDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  143. {
  144.     char s[20];
  145.     static struct values *value; 
  146.     if (msg==WM_INITDIALOG) {
  147.         value=(struct values *)lp;
  148.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  149.            sprintf(s,"%ld",value->val);
  150.         SetDlgItemText(hdlg,VALUE,s);
  151.         }
  152.     if (msg==WM_COMMAND && wp==IDOK) {
  153.         GetDlgItemText(hdlg,VALUE,s,19);
  154.         value->val=atol(s);
  155.         if (value->val < value->from)
  156.             value->val=value->from;
  157.         else if (value->val > value->to)
  158.             value->val=value->to;
  159.         EndDialog(hdlg,1);
  160.         }
  161.     return 0;
  162. }
  163.  
  164.  
  165. // Wrapper for get-a-value dialog. Provides default, ranges, etc...
  166. DWORD GetValue(HWND caller,DWORD defalt,DWORD from,DWORD to)
  167. {
  168.     struct values value;
  169.     value.from=from; value.to=to; value.val=defalt;
  170.     DialogBoxParam(hinst,"ValueDlg",caller,ValueDlgProc,(LPARAM)&value);
  171.     return value.val;
  172. }
  173.  
  174.  
  175. // Record dialog
  176. #pragma argsused
  177. BOOL CALLBACK RecDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  178. {
  179.     static int restartsound=0,autorewind=1,autorepeat=1;
  180.     static int refresh=0;
  181.     static int tnr;                    // track number
  182.     static DWORD start,end;            // Start/ending recording position, redbook format
  183.     static WORD  sm,ss,sf;            // Start recording position: minute, second, frame
  184.     static WORD  em,es,ef;            // idem, End position
  185.     static DWORD sc,ec;                // Start/ending recording sectors
  186.     static char fn[80];                // Last used filename
  187.     DWORD dur;
  188.     WORD  div;
  189.  
  190.     if (msg==WM_INITDIALOG) {
  191.         // Initialize record dialog
  192.         fn[0]=0;                                              // Zap filename
  193.         tnr=(WORD)lp;                                        // Remember track number
  194.         sprintf(s,"Search (track %d)",tracknr[tnr]);        // put it also in the
  195.         SetWindowText(hdlg,s);                                // dialog title
  196.         CenterWindow(hdlg);
  197.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  198.         // Fill inputs with track defaults
  199.         Red2MSFC(start=trackloc[tnr],&sm,&ss,&sf,&sc);
  200.         Red2MSFC(end=trackloc[tnr+1],&em,&es,&ef,&ec);
  201.         // Set scroll bar extents en posities
  202.         SetScrollRange(GetDlgItem(hdlg,SBAR),SB_CTL,0,Red2Sierra(total_time)/75L,0);
  203.         SetScrollRange(GetDlgItem(hdlg,EBAR),SB_CTL,0,Red2Sierra(total_time)/75L,0);
  204.         SetScrollPos(GetDlgItem(hdlg,SBAR),SB_CTL,Red2Sierra(start)/75L,0);
  205.         SetScrollPos(GetDlgItem(hdlg,EBAR),SB_CTL,Red2Sierra(end)/75L,0);
  206.         // Assure all fields will be refreshed; also start playing the track
  207.         refresh=1;
  208.         restartsound=1;
  209.         }
  210.  
  211.     // Button pressed!
  212.     #define FRESH refresh=1; if (autorewind) restartsound=1
  213.     if (msg==WM_COMMAND) {
  214.         if (wp==LISTEN) restartsound=1;
  215.         if (wp==IDOK) {StopAudio(); EndDialog(hdlg,1);}
  216.         if (wp==STEREO) {stereo=1; refresh=1;}
  217.         if (wp==MONO) {stereo=0; refresh=1;}
  218.         if (wp==HZ44) {hz44=1; refresh=1;}
  219.         if (wp==HZ22) {hz44=0; refresh=1;}
  220.         if (wp==BIT16) {bit16=1; refresh=1;}
  221.         if (wp==BIT8) {bit16=0; refresh=1;}
  222.         if (wp==RECORD) {
  223.             StopAudio(); PlayAudio(start,10);            // This prevents sync errors (? beats me but it does!)
  224.             EnableWindow(hdlg,0);                        
  225.             sprintf(fn,"%d-%d-%d.wav",sm,ss,sf);        // Compose a filename using start time
  226.             if (ChooseWavFile(hdlg,fn)) {                // File selection box
  227.                 dur=Red2Sierra(end)-Red2Sierra(start);
  228.                 if (!record(fn,Red2Sierra(start),dur)) mb(error);    // record it.
  229.                 FRESH;
  230.                 }
  231.             EnableWindow(hdlg,1);
  232.             }
  233.         if (wp==EDIT) {
  234.             if (access(fn,0)==0) {                        // Edit only allowed when last used
  235.                 sprintf(s,"%s %s",waveditor,fn);        // is present, and if the file exist.
  236.                 StopAudio();
  237.                 if (WinExec(s,SW_SHOWNORMAL)<32)        // Spawn the WAV editor
  238.                     MessageBox(hdlg,s,"cant execute editor",MB_OK);
  239.                 }
  240.             }
  241.         if (wp==AUTOREWIND) {autorewind=1-autorewind; refresh=1;}
  242.         if (wp==AUTOREPEAT) {autorepeat=1-autorepeat; refresh=1;}
  243.         // Adjusting start time...
  244.         if (wp==SM) {
  245.             sm=GetValue(hdlg,sm,0,99);
  246.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  247.             }
  248.         if (wp==SMDOWN) {
  249.             if (sm) sm--;
  250.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  251.             }
  252.         if (wp==SMUP)   {
  253.             sm++;
  254.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  255.             }
  256.         if (wp==SS) {
  257.             ss=GetValue(hdlg,ss,0,59);
  258.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  259.             }
  260.         if (wp==SSDOWN) {
  261.             if (ss) ss--;
  262.             else if (sm) {sm--; ss=59;}
  263.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  264.             }
  265.         if (wp==SSUP)   {
  266.             ss++;
  267.             if (ss>59) {ss=0; sm++;}
  268.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  269.             }
  270.         if (wp==SF) {
  271.             sf=GetValue(hdlg,sf,0,74);
  272.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  273.             }
  274.         if ((wp==SFDOWN)||(wp==SCDOWN)) {
  275.             if (sf) {
  276.                 sf--;
  277.                 }
  278.             else if (ss) {
  279.                 ss--; sf=74;
  280.                 }
  281.             else if (sm) {
  282.                 sm--; ss=59; sf=74;
  283.                 }
  284.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  285.             }
  286.         if ((wp==SFUP)||(wp==SCUP))   {
  287.             sf++;
  288.             if (sf>74) {
  289.                 sf=0; ss++;
  290.                 if (ss>59) {
  291.                     sm++; ss=0;
  292.                     }
  293.                 }
  294.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  295.             }
  296.         // Adjusting end time...
  297.         if (wp==EM) {
  298.             em=GetValue(hdlg,em,0,99);
  299.             MSF2Red(em,es,ef,&end,&ec);    FRESH;
  300.             }
  301.         if (wp==EMDOWN) {
  302.             if (em) em--;
  303.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  304.             }
  305.         if (wp==EMUP)   {
  306.             em++;
  307.             MSF2Red(em,es,ef,&end,&ec);       FRESH;
  308.             }
  309.         if (wp==ES) {
  310.             es=GetValue(hdlg,es,0,59);
  311.             MSF2Red(em,es,ef,&end,&ec);    FRESH;
  312.             }
  313.         if (wp==ESDOWN) {
  314.             if (es) es--;
  315.             else if (em) {em--; es=59;}
  316.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  317.             }
  318.         if (wp==ESUP)   {
  319.             es++;
  320.             if (es>59) {es=0; em++;}
  321.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  322.             }
  323.         if (wp==EF) {
  324.             ef=GetValue(hdlg,ef,0,74);
  325.             MSF2Red(em,es,ef,&end,&ec);    FRESH;
  326.             }
  327.         if ((wp==EFDOWN)||(wp==ECDOWN)) {
  328.             if (ef) {
  329.                 ef--;
  330.                 }
  331.             else if (es) {
  332.                 es--; ef=74;
  333.                 }
  334.             else if (em) {
  335.                 em--; es=59; ef=74;
  336.                 }
  337.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  338.             }
  339.         if ((wp==EFUP)||(wp==ECUP))   {
  340.             ef++;
  341.             if (ef>74) {
  342.                 ef=0; es++;
  343.                 if (es>59) {
  344.                     em++; es=0;
  345.                     }
  346.                 }
  347.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  348.             }
  349.         }
  350.  
  351.     // Scroll bar?
  352.     if (msg==WM_HSCROLL) { // SBAR, EBAR
  353.         BOOL isstart=0;
  354.         int sc=wp;                // Scrollcode
  355.         int pos=LOWORD(lp);        // position
  356.         if (GetDlgItem(hdlg,SBAR)==(HWND)HIWORD(lp)) isstart=1;
  357.         if (sc==SB_THUMBPOSITION || sc==SB_THUMBTRACK) {
  358.             if (isstart) 
  359.                 Red2MSFC(start=Sierra2Red(75L*pos),&sm,&ss,&sf,&sc);
  360.             else 
  361.                 Red2MSFC(end=Sierra2Red(75L*pos),&em,&es,&ef,&ec);
  362.             FRESH;
  363.             }
  364.         if (sc==SB_LINEUP) {
  365.             if (isstart) {
  366.                 long newstart=Red2Sierra(start)-75L*lineinc;
  367.                 if (newstart<0) newstart=0;
  368.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  369.                 }
  370.             else {
  371.                 long newend=Red2Sierra(end)-75L*lineinc;
  372.                 if (newend<0) newend=0;
  373.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  374.                 }
  375.             FRESH;
  376.             }
  377.         if (sc==SB_LINEDOWN) {
  378.             if (isstart) {
  379.                 long newstart=Red2Sierra(start)+75L*lineinc;
  380.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  381.                 }
  382.             else {
  383.                 long newend=Red2Sierra(end)+75L*lineinc;
  384.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  385.                 }
  386.             FRESH;
  387.             }
  388.         if (sc==SB_PAGEUP) {
  389.             if (isstart) {
  390.                 long newstart=Red2Sierra(start)-75L*pageinc;
  391.                 if (newstart<0) newstart=0;
  392.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  393.                 }
  394.             else {
  395.                 long newend=Red2Sierra(end)-75L*pageinc;
  396.                 if (newend<0) newend=0;
  397.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  398.                 }
  399.             FRESH;
  400.             }
  401.         if (sc==SB_PAGEDOWN) {
  402.             if (isstart) {
  403.                 long newstart=Red2Sierra(start)+75L*pageinc;
  404.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  405.                 }
  406.             else {
  407.                 long newend=Red2Sierra(end)+75L*pageinc;
  408.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  409.                 }
  410.             FRESH;
  411.             }
  412.         }
  413.  
  414.  
  415.     // Something needs redrawing? Well, redraw them all.
  416.     if (refresh) {
  417.         refresh=0;
  418.         // Never play outside CD tracks - may hang the driver
  419.         if (start<trackloc[0])         Red2MSFC(start=trackloc[0],&sm,&ss,&sf,&sc);
  420.         if (start>trackloc[ntrack]) Red2MSFC(start=trackloc[ntrack],&sm,&ss,&sf,&sc);
  421.         if (end<trackloc[0])         Red2MSFC(end=trackloc[0],&em,&es,&ef,&ec);
  422.         if (end>trackloc[ntrack])     Red2MSFC(end=trackloc[ntrack],&em,&es,&ef,&ec);
  423.         if (start>end)                 Red2MSFC(end=start,&em,&es,&ef,&ec);
  424.         // Update the numerals in the edit controls
  425.         Red2MSFC(start,&sm,&ss,&sf,&sc);
  426.         Red2MSFC(end,&em,&es,&ef,&ec);
  427.  
  428.         SetDlgItemInt(hdlg,SM,sm,0);    SetDlgItemInt(hdlg,SS,ss,0);
  429.         SetDlgItemInt(hdlg,SF,sf,0);
  430.         sprintf(s,"%lu",sc); SetDlgItemText(hdlg,SC,s);
  431.  
  432.         SetDlgItemInt(hdlg,EM,em,0);    SetDlgItemInt(hdlg,ES,es,0);
  433.         SetDlgItemInt(hdlg,EF,ef,0);
  434.         sprintf(s,"%lu",ec); SetDlgItemText(hdlg,EC,s);
  435.         // Update scroll bars
  436.         SetScrollPos(GetDlgItem(hdlg,SBAR),SB_CTL,Red2Sierra(start)/75L,1);
  437.         SetScrollPos(GetDlgItem(hdlg,EBAR),SB_CTL,Red2Sierra(end)/75L,1);
  438.  
  439.         // Set radiobuttons
  440.         if (!bit16) {
  441.             hz44=0; stereo=0;
  442.             EnableWindow(GetDlgItem(hdlg,HZ22),0);
  443.             EnableWindow(GetDlgItem(hdlg,HZ44),0);
  444.             EnableWindow(GetDlgItem(hdlg,MONO),0);
  445.             EnableWindow(GetDlgItem(hdlg,STEREO),0);
  446.             }
  447.         else {
  448.             EnableWindow(GetDlgItem(hdlg,HZ22),1);
  449.             EnableWindow(GetDlgItem(hdlg,HZ44),1);
  450.             EnableWindow(GetDlgItem(hdlg,MONO),1);
  451.             EnableWindow(GetDlgItem(hdlg,STEREO),1);
  452.             }
  453.         CheckRadioButton(hdlg,MONO,STEREO,stereo?STEREO:MONO);
  454.         CheckRadioButton(hdlg,HZ22,HZ44,hz44?HZ44:HZ22);
  455.         CheckRadioButton(hdlg,BIT8,BIT16,bit16?BIT16:BIT8);
  456.         CheckDlgButton(hdlg,AUTOREWIND,autorewind);
  457.         CheckDlgButton(hdlg,AUTOREPEAT,autorepeat);
  458.         if (*fn && access(fn,0)==0)
  459.             EnableWindow(GetDlgItem(hdlg,EDIT),1);
  460.         else
  461.             EnableWindow(GetDlgItem(hdlg,EDIT),0);
  462.         // Calculate projected file size and duration
  463.         dur=Red2Sierra(end)-Red2Sierra(start);
  464.         div=0; if (!stereo) div++; if (!hz44) div++; if (!bit16) div++;
  465.         sprintf(s,"%ld Kbytes",((dur*2352)>>div)/1024);
  466.         SetDlgItemText(hdlg,FSIZE,s);
  467.         sprintf(s,"%s   /  %ld sectors",Sector2MSF(dur),dur);
  468.         SetDlgItemText(hdlg,DUR,s);
  469.         }
  470.  
  471.     // Issue a play command to the CD player
  472.     if (restartsound) {
  473.         restartsound=0;
  474.         StopAudio();
  475.         PlayAudio(start,Red2Sierra(end)-Red2Sierra(start));
  476.         }
  477.     return 0;
  478. }
  479.  
  480.  
  481. // Preferences dialog proc
  482. #pragma argsused
  483. BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  484. {
  485.     if (msg==WM_INITDIALOG) {
  486.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  487.         sprintf(s,"%d audio buffers allocated",nbuf);
  488.         SetDlgItemText(hdlg,BUFRESULT,s);
  489.         SetDlgItemText(hdlg,WAVEDITOR,waveditor);
  490.         }
  491.     if (msg==WM_COMMAND && wp==IDOK) {
  492.         GetDlgItemText(hdlg,WAVEDITOR,waveditor,159);
  493.         WriteProfileString("Digital Domain","WAVeditor",waveditor);
  494.         EndDialog(hdlg,1);
  495.         }
  496.     return 0;
  497. }
  498.  
  499. // Sync error dialog proc
  500. #pragma argsused
  501. BOOL CALLBACK SyncErrDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  502. {
  503.     if (msg==WM_INITDIALOG) SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  504.     if (msg==WM_COMMAND) {
  505.         if (wp==ABOUT) {
  506.             WinHelp(hdlg,HELPFILE,HELP_KEY,"SyncErr");
  507.             EndDialog(hdlg,1);
  508.             }
  509.         if (wp==IDCANCEL) {
  510.             EndDialog(hdlg,1);
  511.             }
  512.         }
  513.     return 0;
  514. }
  515.  
  516. // Memalloc error dialog proc
  517. #pragma argsused
  518. BOOL CALLBACK MemErrDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  519. {
  520.     if (msg==WM_INITDIALOG) SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  521.     if (msg==WM_COMMAND) {
  522.         if (wp==ABOUT) {
  523.             WinHelp(hdlg,HELPFILE,HELP_KEY,"MemErr");
  524.             EndDialog(hdlg,1);
  525.             }
  526.         if (wp==IDCANCEL) {
  527.             EndDialog(hdlg,1);
  528.             }
  529.         }
  530.     return 0;
  531. }
  532.  
  533. // Main dialog proc
  534. #pragma argsused
  535. BOOL CALLBACK MainDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  536. {
  537.     int i;
  538.     if (msg==WM_INITDIALOG) {
  539.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  540.         // Infoheaderts at top 
  541.         SetDlgItemText(hdlg,PLAYINGTIME,Sector2MSF(Red2Sierra(total_time)));
  542.         sprintf(s,"%d",highest-lowest+1);
  543.         SetDlgItemText(hdlg,NRTRACKS,s);
  544.         // Track table
  545.         if (!BuildTrackTable()) mb("Error building the track table");
  546.         SendDlgItemMessage(hdlg,TRACKLIST,LB_RESETCONTENT,0,0);
  547.         for (i=0;i<ntrack;i++) {
  548.             strcpy(t,Red2MSF(trackloc[i]));
  549.             sprintf(s," %2d.   %s     start at %s    %ld sectors",
  550.                         tracknr[i],
  551.                         Sector2MSF(tracklen[i]),
  552.                         Red2MSF(trackloc[i]),
  553.                         tracklen[i]
  554.                         );
  555.             SendDlgItemMessage(hdlg,TRACKLIST,LB_ADDSTRING,0,(LPARAM)s);
  556.             }
  557.         }
  558.     // Some button or track line clicked?
  559.     if (msg==WM_COMMAND) {
  560.         if (HIWORD(lp)==LBN_SELCHANGE) {
  561.             int item;
  562.             if (hlogo) ToggleLogo();
  563.             item=(WORD)SendDlgItemMessage(hdlg,TRACKLIST,LB_GETCURSEL,0,0L);
  564.             if (item!=LB_ERR) {
  565.                 EnableWindow(hdlg,0);
  566.                 if (-1==DialogBoxParam(hinst,"RecDlg",0,RecDlgProc,item))
  567.                     mb("cant create record dialog");
  568.                 EnableWindow(hdlg,1); SetFocus(GetDlgItem(hdlg,TRACKLIST));
  569.                 }
  570.             }
  571.         else {
  572.             if (wp==PREFS) {
  573.                 EnableWindow(hdlg,0);
  574.                 DialogBox(hinst,"PrefDlg",0,PrefDlgProc);
  575.                 EnableWindow(hdlg,1); SetFocus(GetDlgItem(hdlg,TRACKLIST));
  576.                 }
  577.             if (wp==QUIT || wp==EJECT) {StopAudio(); EndDialog(hdlg,wp);}
  578.             if (wp==ABOUT) WinHelp(GetDesktopWindow(),HELPFILE,HELP_CONTENTS,0);
  579.             }
  580.         }
  581.     return 0;
  582. }
  583.  
  584.  
  585. // Mainprogram entry point
  586. #pragma argsused
  587. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int cmdShow)
  588. {
  589.     MSG msg;
  590.     int try,status,result;
  591.     hinst=hInstance;
  592.  
  593.     // Allocate buffers in low memory
  594.     if (!startinterfacing()) {
  595.         DialogBox(hInstance,"MemErrDlg",0,MemErrDlgProc);
  596.         return 0;
  597.         }
  598.     // Is MSCDEX installed? If not, abort.
  599.     if (!CheckMscdex()) {
  600.         mb("MSCDEX not installed");
  601.         return 0;
  602.         }
  603.     // Display logo
  604.     RegisterLogo(hinst);
  605.     ToggleLogo();
  606.     // Give some time slices so the logo will display
  607.     while (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
  608.         TranslateMessage(&msg);
  609.            DispatchMessage(&msg);
  610.         }
  611.     // Wait a bit
  612.     delay(CLK_TCK*2);
  613. Rescan:
  614.     // Get global information about CD
  615.     status=GetDiskInfo(); try=0;
  616.     while (status!=0x0100) {
  617.         delay(CLK_TCK);
  618.         if (++try>=3) {
  619.             if (MessageBox(0,"Insert an audio CD in the drive","CDROM is busy",MB_RETRYCANCEL)==IDCANCEL) {
  620.                 // ieks... terminate
  621.                 stopinterfacing();
  622.                 return 0;
  623.                 }
  624.             try=0;
  625.             }
  626.         status=GetDiskInfo();
  627.         }
  628.     // Do the interaction
  629.     GetProfileString("Digital Domain","WAVeditor",waveditor,waveditor,159);
  630.     result=DialogBox(hinst,"MainDlg",0,MainDlgProc);
  631.     if (result==EJECT) {
  632.         // Try MCI, for a change
  633.         mciSendString("SET CDAUDIO DOOR OPEN", NULL, 0, NULL ); // This one works OK on my drive...
  634.         MessageBox(0,"You can change the CD now","Digital Domain",MB_OK);
  635.         mciSendString("SET CDAUDIO DOOR CLOSED", NULL, 0, NULL ); // This does NOT work on my drive...
  636.         delay(6*CLK_TCK);
  637.         goto Rescan;
  638.         }
  639.     WinHelp(GetDesktopWindow(),HELPFILE,HELP_QUIT,0);
  640.     // Free up
  641.     stopinterfacing();
  642.     if (hlogo) ToggleLogo();
  643.     return 0;
  644. }
  645.